package com.gitee.base.utils;

import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.DecodedJWT;
import lombok.extern.slf4j.Slf4j;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.net.InetAddress;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.net.UnknownHostException;

/**
 * 工具包
 */
@Slf4j
public class Kit {
    private static final String SECRET = "~!@#$%^&*()";
    private static final String TOKEN_KEY = "sid";
    private static final String COOKIE_KEY = "base_sid";

    /**
     * 生成token
     * @param key 保存在token中的值
     * @return 返回一个token
     */
    public static String createToken(String key) {
        Algorithm algorithm = Algorithm.HMAC256(SECRET);
        String token = JWT.create()
                .withIssuer("auth0")
                .withClaim(TOKEN_KEY, key)
                .sign(algorithm);
        return token;
    }

    /**
     * 校验token
     * @param token 待校验的token
     * @return 返回保存在token中的值
     */
    public static String verifyToken(String token){
        Algorithm algorithm = Algorithm.HMAC256(SECRET);
        JWTVerifier verifier = JWT.require(algorithm)
                .withIssuer("auth0")
                .build();
        DecodedJWT jwt = verifier.verify(token);
        return jwt.getClaim(TOKEN_KEY).asString();
    }

    /**
     * 获取cookie的值
     * @param request
     * @return
     */
    public static String getCookieToken(HttpServletRequest request){
        try{
            Cookie[] cookies = request.getCookies();
            if(cookies!=null){
                for(Cookie cookie:cookies){
                    if(cookie.getName().equals(COOKIE_KEY)){
                        return URLDecoder.decode(cookie.getValue(),"utf-8");
                    }
                }
            }
        }catch (Exception e){
            throw new RuntimeException("读取cookie出错", e);
        }
        return null;
    }

    /**
     * 添加cookie
     * @param response
     * @param value
     * @param time
     */
    public static void addCookieToken(HttpServletResponse response, String value, int time){
        try{
            Cookie cookie = new Cookie(COOKIE_KEY, URLEncoder.encode(value,"utf-8"));
            cookie.setHttpOnly(true);
            cookie.setMaxAge(time==0?-1:time);
            cookie.setPath("/");
            cookie.setSecure(false);
            response.addCookie(cookie);
        }catch (Exception e){
            throw new RuntimeException("添加cookie出错", e);
        }
    }

    /**
     * 清理cookie
     * @param response
     */
    public static void clearCookie(HttpServletResponse response){
        try{
            Cookie cookie = new Cookie(COOKIE_KEY, null);
            cookie.setMaxAge(0);
            cookie.setHttpOnly(true);
            cookie.setPath("/");
            cookie.setSecure(false);
            response.addCookie(cookie);
        }catch (Exception e){
            throw new RuntimeException("添加cookie出错", e);
        }
    }


    /**
     * 获取请求的ip
     * @param request
     * @return
     */
    public static String getIp(HttpServletRequest request) {
        String ip = request.getHeader("X-Forwarded-For");
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("HTTP_CLIENT_IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("X-Real-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
        }
        if (ip != null) {
            if(ip.indexOf(",") > 0){
                ip = ip.split(",")[0];
            }else{
                if (ip.equals("0:0:0:0:0:0:0:1")) {
                    InetAddress addr = null;
                    try {
                        addr = InetAddress.getLocalHost();
                    } catch (UnknownHostException e) {
                        log.error(e.getMessage(), e);
                    }
                    ip = null2String(addr.getHostAddress());// 获得本机IP
                }
            }

        }
        return ip;
    }

    private static String null2String(Object s) {
        return s == null ? "" : s.toString().trim();
    }

}
